package com.foreveredu.erlms.web.struts.action;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;

import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.foreveredu.erlms.domain.Enroll;
import com.foreveredu.erlms.domain.Examinee;
import com.foreveredu.erlms.service.IExamService;

import com.foreveredu.erlms.web.util.DBFWriterTool;
import com.foreveredu.erlms.web.util.ZipCompress;
import com.linuxense.javadbf.DBFReader; 

/*
 * @author hushigang 2012/4/16
 * DataIOAction负责处理数据的导入导出请求
 */
public class DataIOAction extends AbstractBaseDispatchAction {

	private IExamService examService = null;

//	private Logger log = Logger.getLogger(DataIOAction.class);

	public IExamService getExamService() {
		return examService;
	}

	public void setExamService(IExamService examService) {
		this.examService = examService;
	}

	// 导出考生报名表bmk.dbf
	public ActionForward buildDBF(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		// 获得当前考试届次
		int examOrder = examService.getExamOrderOfNow();
		List<Enroll> enList = examService.findEnrollsByExamOrder(examOrder);

		response.setContentType("application/x-dbf;charset=GBK");
		response.setHeader("Content-Disposition",
				"attachment;filename=\"bmk.dbf\"");
		DBFWriterTool.buildDBF(enList, response.getOutputStream());

		return null;
	}

	// 按班级排序导出未交费学生报名表bmkNoPaid.dbf
	public ActionForward buildNoPaidDBF(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		// 获得当前考试届次
		int examOrder = examService.getExamOrderOfNow();
		List<Enroll> enList = examService
				.findNoPaidEnrollsByExamOrder(examOrder);

		response.setContentType("application/x-dbf;charset=GBK");
		response.setHeader("Content-Disposition",
				"attachment;filename=\"bmkNoPaid.dbf\"");
		DBFWriterTool.buildNoPaidDBF(enList, response.getOutputStream());

		return null;
	}

	// 导出考生相片
	public ActionForward zipPhoto(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		// 读取考生上传照片的photo文件夹
		String dirPath = request.getSession().getServletContext().getRealPath(
				"/photo");
		File fileDir1 = new File(dirPath);
		String basePath = fileDir1.getPath();
		// log.info("/basePath"+ basePath);

		// 读取照片压缩的文件夹及文件名photo.zip
		String zipPath = request.getSession().getServletContext().getRealPath(
				"/photo.zip");
		File fileDir2 = new File(zipPath);
		String photozip = fileDir2.getPath();
		// log.info("/photozip"+ photozip);

		// 开始压缩照片
		ZipCompress zc = new ZipCompress(basePath, photozip);
		zc.compress();

		// 下载照片
		response.setContentType("application/zip;charset=UTF-8");
		response.setHeader("Content-Disposition",
				"attachment;filename=\"photo.zip\"");

		ServletOutputStream out = response.getOutputStream();
		BufferedOutputStream bos = new BufferedOutputStream(out);

		FileInputStream fis = new FileInputStream(zipPath);
		byte[] b = new byte[2048];
		int num = 0;
		while ((num = fis.read(b)) != -1) {
			bos.write(b, 0, num);
		}
		bos.flush();

		//照片下载完毕后，清空/photo文件夹下的所有文件
		File[] photoFiles = fileDir1.listFiles();
		for(int i = 0; i < photoFiles.length; i++) {
			photoFiles[i].delete();
		}
		
		fis.close();
		out.close();
		bos.close();

		return null;
	}

	// 上传考生准考证号信息（DBF）
	@SuppressWarnings("unchecked")
	public ActionForward readDBF(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		// 获得当前考试届次
		int examOrder = examService.getExamOrderOfNow();

		// 将考生上传照片保存到photo文件夹中
		String dirPath = request.getSession().getServletContext().getRealPath(
				"/zkzhDBF");

		// 判断路径是否存在，如果不存在，就创建这个路径
		File fileDir = new File(dirPath);
		if (!fileDir.exists()) {
			fileDir.mkdir();
		}

		Hashtable<Object, Object> files = form.getMultipartRequestHandler()
				.getFileElements();

		String zkzhDBF = null;

		for (Enumeration<Object> e = files.keys(); e.hasMoreElements();) {
			String key = (String) e.nextElement();

			try {
				FormFile formFile = (FormFile) files.get(key);
				String fileName = formFile.getFileName().trim();// 获得待上传的文件名

				if (fileName == null || fileName.equals("")) {
					request.setAttribute("fileEmptyError", "上传的DBF文件为空！");
					return mapping.findForward("readDBF");
				}

				// 获得当天日期
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
				String datetime = sdf.format(date);

				// 保存后的文件名不能使用原来的,可以防止下载出错
				// 新文件名为当前日期+当前考试届次
				String newFileName = datetime + examOrder;

				// 读出原文件的扩展名
				String ext = "";
				int pos = fileName.lastIndexOf(".");
				ext = fileName.substring(pos);// 得到扩展名

				if (!ext.equalsIgnoreCase(".DBF")) {
					request.setAttribute("fileFormatError", "文件格式不对，只能是DBF格式！");
					return mapping.findForward("readDBF");
				}

				// 拼出完整的新文件名:
				zkzhDBF = newFileName + ext;

				InputStream is = formFile.getInputStream();
				OutputStream os = new FileOutputStream(dirPath
						+ File.separatorChar + zkzhDBF);

				int bytesRead = 0;
				byte[] buffer = new byte[8192];
				while ((bytesRead = is.read(buffer)) != -1) {
					os.write(buffer, 0, bytesRead);
				}
				os.flush();

				is.close();
				os.close();

			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}

		String path = dirPath + File.separatorChar + zkzhDBF;

		InputStream fis = null;
		try {
			fis = new FileInputStream(path);
			DBFReader reader = new DBFReader(fis);
			reader.setCharactersetName("GBK");

			// 从DBF文件中读取报名号，通过报名号查找到相应的考生，将其准考证号修改为DBF文件中相应的准考证号
			Object[] rowValues = null;
			while ((rowValues = reader.nextRecord()) != null) {
				Examinee examinee = null;
				examinee = examService.findExamineeByEnrollNumber(
						(String) rowValues[1], examService.getExamOrderOfNow());
				if (examinee != null) {
					examinee.setTicketNumber((String) rowValues[0]);
					examService.updateExaminee(examinee);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fis.close();
			} catch (Exception e) {
			}
		}
		request.setAttribute("readDBFSuccess", "导入数据成功");
		return mapping.findForward("readDBFSuccess");
	}

	// 上传已交费考生的网报号信息，并批量确认
	@SuppressWarnings("unchecked")
	public ActionForward readWbhDBF(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		// 获得当前考试届次
		int examOrder = examService.getExamOrderOfNow();

		// 将考生上传照片保存到photo文件夹中
		String dirPath = request.getSession().getServletContext().getRealPath(
				"/wbhDBF");

		// 判断路径是否存在，如果不存在，就创建这个路径
		File fileDir = new File(dirPath);
		if (!fileDir.exists()) {
			fileDir.mkdir();
		}

		Hashtable<Object, Object> files = form.getMultipartRequestHandler()
				.getFileElements();

		String wbhDBF = null;

		for (Enumeration<Object> e = files.keys(); e.hasMoreElements();) {
			String key = (String) e.nextElement();

			try {
				FormFile formFile = (FormFile) files.get(key);
				String fileName = formFile.getFileName().trim();// 获得待上传的文件名

				if (fileName == null || fileName.equals("")) {
					request.setAttribute("fileEmptyError", "上传的DBF文件为空！");
					return mapping.findForward("readDBF");
				}

				// 获得当天日期
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
				String datetime = sdf.format(date);

				// 保存后的文件名不能使用原来的,可以防止下载出错
				// 新文件名为当前日期+当前考试届次
				String newFileName = datetime + examOrder;

				// 读出原文件的扩展名
				String ext = "";
				int pos = fileName.lastIndexOf(".");
				ext = fileName.substring(pos);// 得到扩展名

				if (!ext.equalsIgnoreCase(".DBF")) {
					request.setAttribute("fileFormatError", "文件格式不对，只能是DBF格式！");
					return mapping.findForward("readDBF");
				}

				// 拼出完整的新文件名:
				wbhDBF = newFileName + ext;

				InputStream is = formFile.getInputStream();
				OutputStream os = new FileOutputStream(dirPath
						+ File.separatorChar + wbhDBF);

				int bytesRead = 0;
				byte[] buffer = new byte[8192];
				while ((bytesRead = is.read(buffer)) != -1) {
					os.write(buffer, 0, bytesRead);
				}
				os.flush();

				is.close();
				os.close();

			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}

		String path = dirPath + File.separatorChar + wbhDBF;

//		log.info("wbhDBF="+path);
		//统计批量确认成功的学生数量
		int count = 0;
		InputStream fis = null;
		try {
			fis = new FileInputStream(path);
			DBFReader reader = new DBFReader(fis);
			reader.setCharactersetName("GBK");

			// 从DBF文件中读取网报号，通过网报号查找到相应的考生，将这些已缴费学生的信息批量确认，即生成报名号，并设置交费状态为1
			Object[] rowValues = null;
			while ((rowValues = reader.nextRecord()) != null) {
				Examinee examinee = null;
				examinee = examService.findExamineeBySerialNumber(
						(String) rowValues[0], examService.getExamOrderOfNow());
//				log.info(examinee.getSerialNumber());
				//避免重复提交，所以应该判断当前考生的交费状态是否为0
				if (examinee != null && examinee.getEnroll().getIsPaid() == 0) {
					Enroll enroll = examinee.getEnroll();

					// 当考生交费后，生成该考生的报名号，
					String enrollNumber = examService.getMaxENRecord(enroll.getRank().getCode());
					examinee.setEnrollNumber(enrollNumber);
					examService.updateExaminee(examinee);

					// 修改该考生的相片的文件名为报名号
					String photo = request.getSession().getServletContext()
							.getRealPath("/photo/" + enroll.getIcon());
					File file = new File(photo);
//					log.info(photo);

					String newPhoto = request.getSession().getServletContext()
							.getRealPath("/photo/" + enrollNumber + ".jpg");
					File newFile = new File(newPhoto);
//					log.info(newPhoto);

					if (file != null) {
						file.renameTo(newFile);
					}

					enroll.setIcon(enrollNumber + ".jpg");

					// 将当前日期储存到enroll中
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					String now = sdf.format(new Date());
					enroll.setPaidTime(now);
					// 设置交费状态为1
					enroll.setIsPaid(1);
					
					examService.updateEnroll(enroll);
					count++;//每确认成功一个学生，则计数器加1
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fis.close();
			} catch (Exception e) {
			}
		}
		request.setAttribute("readWbhDBFSuccess", "导入已交费考生信息成功，并批量确认"+count+"个考生的信息！");
		return mapping.findForward("readWbhDBFSuccess");
	}
}
